package Jets.ui
{
   import flash.display.DisplayObjectContainer;
   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.geom.Rectangle;
   import Jets.display.JContainer;
   
   public class JSlider extends JContainer
   {
	   public static const HORIZONTAL:String = "horizontal";
	   public static const VERTICAL:String = "vertical";
	   
	   protected var _handle:JPanel;
	   private var _back:JPanel;
	   private var _backClick:Boolean = true;
	   protected var _value:Number = 0;
	   protected var _max:Number = 100;
	   protected var _min:Number = 0;
	   protected var _orientation:String;
	   
      public function JSlider(type:String=HORIZONTAL,parent:DisplayObjectContainer=null,cx:Number=0,cy:Number=0,change:Function=null) 
	  {
         this._orientation = type;
         super(parent,cx,cy);
         if(change != null)
         {
            addEventListener(Event.CHANGE,change);
         }
      }
      

      override protected function init() : void 
	  {
         super.init();
         if(this._orientation == HORIZONTAL)
         {
            setSize(100,10);
         }
         else
         {
            setSize(10,100);
         }
      }
      
      override protected function addChildren() : void 
	  {
         this._back = new JPanel(this);
         addChild(this._back);
         this._handle = new JPanel(this);
         this._handle.addEventListener(MouseEvent.MOUSE_DOWN,this.onDrag);
         this._handle.buttonMode = true;
         this._handle.useHandCursor = true;
         addChild(this._handle);
      }
      
      public function set handleskin(skinName:String) : void 
	  {
         this._handle.skin = skinName;
      }
      
      public function set backskin(skinName:String) : void 
	  {
         this._back.skin = skinName;
      }
      
      protected function drawBack() : void 
	  {
         this._back.setSize(_width,_height);
         if(this._backClick)
         {
            this._back.addEventListener(MouseEvent.MOUSE_DOWN,this.onBackClick);
         }
         else
         {
            this._back.removeEventListener(MouseEvent.MOUSE_DOWN,this.onBackClick);
         }
      }
      
      protected function drawHandle() : void 
	  {
         if(this._orientation == HORIZONTAL)
         {
            this._handle.move(1,1);
            this._handle.setSize(_height - 2,_height - 2);
            this._handle.graphics.drawRect(1,1,_height - 2,_height - 2);
         }
         else
         {
            this._handle.move(1,1);
            this._handle.setSize(_width - 2,_width - 2);
         }
         this.positionHandle();
      }
      
      private function correctValue() : void 
	  {
         if(this._max > this._min)
         {
            this._value = Math.min(this._value,this._max);
            this._value = Math.max(this._value,this._min);
         }
         else
         {
            this._value = Math.max(this._value,this._max);
            this._value = Math.min(this._value,this._min);
         }
      }
      
      protected function positionHandle() : void 
	  {
         var position:Number
         if(this._orientation == HORIZONTAL)
         {
			 position = width - height;
            this._handle.x = (this._value - this._min) / (this._max - this._min) * position;
         }
         else
         {
			 position = height - width;
            this._handle.y = position - (this._value - this._min) / (this._max - this._min) * position;
         }
      }
      
      override public function draw() : void 
	  {
         super.draw();
         this.drawBack();
         this.drawHandle();
      }
      
      public function setSliderParams(min:Number, max:Number, pos:Number) : void 
	  {
         this.minimum = min;
         this.maximum = max;
         this.value = pos;
      }
      
      private function onBackClick(event:MouseEvent) : void 
	  {
         if(this._orientation == HORIZONTAL)
         {
            this._handle.x = mouseX - height / 2;
            this._handle.x = Math.max(this._handle.x,0);
            this._handle.x = Math.min(this._handle.x,width - height);
            this._value = this._handle.x / (width - height) * (this._max - this._min) + this._min;
         }
         else
         {
            this._handle.y = mouseY - width / 2;
            this._handle.y = Math.max(this._handle.y,0);
            this._handle.y = Math.min(this._handle.y,height - width);
            this._value = (_height - _width - this._handle.y) / (height - width) * (this._max - this._min) + this._min;
         }
         dispatchEvent(new Event(Event.CHANGE));
      }
      
      protected function onDrag(event:MouseEvent) : void 
	  {
         stage.addEventListener(MouseEvent.MOUSE_UP,this.onDrop);
         stage.addEventListener(MouseEvent.MOUSE_MOVE,this.onSlide);
         if(this._orientation == HORIZONTAL)
         {
            this._handle.startDrag(false,new Rectangle(0,0,width - height,0));
         }
         else
         {
            this._handle.startDrag(false,new Rectangle(0,0,0,height - width));
         }
      }
      
      protected function onDrop(event:MouseEvent) : void 
	  {
		  event.target.stage.removeEventListener(MouseEvent.MOUSE_UP,this.onDrop);
		  event.target.stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.onSlide);
         stopDrag();
      }
      
      protected function onSlide(event:MouseEvent) : void 
	  {
         var _loc2_:Number = this._value;
         if(this._orientation == HORIZONTAL)
         {
            this._value = this._handle.x / (width - height) * (this._max - this._min) + this._min;
         }
         else
         {
            this._value = (_height - _width - this._handle.y) / (height - width) * (this._max - this._min) + this._min;
         }
         if(this._value != _loc2_)
         {
            dispatchEvent(new Event(Event.CHANGE));
         }
      }
      
      public function set backClick(bool:Boolean) : void 
	  {
         this._backClick = bool;
         invalidate();
      }
      
      public function get backClick() : Boolean 
	  {
         return this._backClick;
      }
      
	  /**当前值*/
      public function set value(value:Number) : void 
	  {
         this._value = value;
         this.correctValue();
         this.positionHandle();
      }
      public function get value() : Number 
	  {
         return this._value;
      }
      
	  /**最大值*/
      public function set maximum(value:Number) : void 
	  {
         this._max = value;
         this.correctValue();
         this.positionHandle();
      }
      public function get maximum() : Number 
	  {
         return this._max;
      }
      
	  /**最小值*/
      public function set minimum(value:Number) : void {
         this._min = value;
         this.correctValue();
         this.positionHandle();
      }
      public function get minimum() : Number 
	  {
         return this._min;
      }
   }
}
